import json
import logging
from base64 import b64decode
from hashlib import md5
from pathlib import Path
from time import sleep

from playhouse.shortcuts import model_to_dict
from wsc_core import flag, models

from utils import glb

flag.parser.add_argument('--u-id', help='User ID')
flag.parser.add_argument('--u-token', help='User Token')
args = flag.parser.parse_args()

question_types = {
    '1': 0,
    '2': 1,
    '4': 2,
}

path = Path('questions.json')
question_list = []


def get_base64_obj(value):
    if isinstance(value, str):
        return b64decode(value).decode().strip()
    else:
        return Base64Dict(value)


class Base64Dict:
    def __init__(self, value):
        self.value = value
        if isinstance(value, dict):
            self.type = dict
        elif isinstance(value, list):
            self.type = list
        else:
            raise Exception('非预期的类型', value)

    def __getitem__(self, item):
        value = self.value[item]
        return get_base64_obj(value)

    def __iter__(self):
        for value in self.value:
            yield get_base64_obj(value)


def send_request(method, **kwargs):
    params = kwargs['params']
    params.update({
        'VipType': 'isvip',
        'UserID': args.u_id,
        'UserToken': args.u_token,
        'AppSource': 'kszlw_android',
        'source': 'kszlw_android',
        'AndroidVID': '16',
        'AndroidVersion': '3.0.1228',
    })
    headers = kwargs.setdefault('headers', {})
    headers.update({
        'AppVersion': '3.0.1228',
        'User-Agent': 'com.pptiku.kaoshitiku',
        'source': 'kszlw_android',
        'Accept-Encoding': 'gzip',
    })
    params['sign'] = md5(''.join(('='.join(i) for i in sorted(params.items()))).encode()).hexdigest()
    while True:
        response = glb.client.send_request(method, **kwargs)
        result = Base64Dict(response.json())
        if result['S'] == '0':
            if '已学完' in result['msg']:
                return
            logging.info(result['msg'])
            sleep(3)
            continue
        elif result['S'] == '5':
            logging.info(result['msg'])
            input()
        else:
            return result


def main():
    while True:
        questions = send_request(
            'get', url='https://newapi.ppkao.com/api/ExamApi/GetUserExamList',
            params={
                'examNum': '100',
                'examType': '1,2,4',
                'typeId': '13208',
                'doType': 'notdo',
            }
        )
        for question in questions['Examlist']:
            exam_type = question['Exam_Type']
            if exam_type not in question_types:
                logging.info('非预期的题型')
                continue
            question_type = int(question_types[exam_type])
            question_str = question['Wenti']
            options = {
                f"answer_{chr(i + ord('a'))}": option['option'] for i, option in enumerate(question['optionList'])
            }
            question_db = models.Question(
                question=question_str,
                analysis=question['Analysis'],
                **options,
                type=question_type,
                answer_count=question['answertimes'],
                correct_count=question['accuracy'],
                # chapter_uuid=guess_chapter(f"{question_str} {options.values()}"),
                is_exam_question=False,
            )
            if question_type in (0, 1):
                if len(question['optionList']) > 8:
                    logging.info('过长的选项')
                    continue
                else:
                    for i, answer in enumerate(question['Answer'].split(', ')):
                        setattr(question_db, f"is_{answer.lower()}", True)
            elif question_type == 4:
                question_db.is_true = bool(int(question['Answer']))
            question_list.append(model_to_dict(question_db))
            send_request(
                'get', url='https://newapi.ppkao.com/api/ExamApi/saveAnswer',
                params={
                    'IsErrTK': '0',
                    'Content': f"{question['ExamID']}[-]0[-]{'0' if question_type == 4 else 'A'}[-]{exam_type}",
                    'ExamID': question['ExamID'],
                }
            )
        logging.info(f'{len(question_list)=}')
        # sleep(1)


try:
    main()
except TypeError:
    path.write_text(json.dumps(question_list, ensure_ascii=False))
